
#pragma once

using namespace System::ComponentModel;
using namespace System::Collections::Generic;

namespace ttg_internal
{
	namespace utils
	{
		///<summary>
		///Contains information about one device subsystem (e.g. one core of CPU).
		///</summary>
		public ref class SubSystemInfo : public INotifyPropertyChanged,
										 public System::ICloneable
		{
			private:
				System::String ^_name;
				double _usage;
				double _maxValue;
				System::String ^_unitName;
				///<summary>
				/// Notifies about updated property.
				///</summary>
				void NotifyPropertyChanged(System::String ^info)
				{
					PropertyChanged(this, gcnew PropertyChangedEventArgs(info));
				}
			internal:
				///<summary>
				///Creates empty subsytem with given name.
				///</summary>
				SubSystemInfo(System::String ^name,
							  System::String ^unitName,
							  double maxValue)
				{
					_name = name;
					_unitName = unitName;
					_maxValue = maxValue;
					_usage = 0.0;
				}
			public:
				///<summary>
				/// Event for INotifyPropertChanged.
				///</summary>
				virtual event PropertyChangedEventHandler ^PropertyChanged;
    			///<summary>
				/// Returns name of subsystem (e.g. "Core #1", "Memory", etc).
				///</summary>
				property System::String ^Name
				{
					System::String ^get()
					{ return _name; }
				}
				///<summary>
				/// Returns name of measuring unit.
				///<summary>
				property System::String ^UnitName
				{
					System::String ^get()
					{ return _unitName; }
				}
				///<summary>
				/// Sets or returns normalized usage of current subsystem (from 0.0 to 1.0).
				///</summary>
				property double Usage
				{
					double get()
					{ return _usage; }
					void set(double value)
					{
						_usage = value;
						NotifyPropertyChanged("Usage");
					}
				}
				///<summary>
				/// Returns maximal achievable value (that is equal to usage == 1.0).
				///<summary>
				property double MaxValue
				{
					double get()
					{ return _maxValue; }
				}
				virtual System::String ^ToString() override
				{
					return System::String::Format("{0}: {1:N} {2}", Name, Usage * MaxValue, UnitName);
				}
				virtual Object ^Clone()
				{
					SubSystemInfo ^ssi = gcnew SubSystemInfo(Name, UnitName, MaxValue);
					ssi->Usage = Usage;
					return ssi;
				}
		};
	}
}
